package com.bckj.fastboot.core.util;


import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;

import java.util.Set;

/**
 * 校验工具类
 * 提供基于 javax.validation.constraints 注解的校验功能
 */
public class ValidationUtils {

    // 使用默认的验证工厂
    private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
    
    // 获取验证器实例
    private static final Validator validator = factory.getValidator();

    /**
     * 校验对象
     * @param object 待校验的对象
     * @param <T> 对象类型
     * @return 校验结果，如果通过校验则返回空集合
     */
    public static <T> Set<ConstraintViolation<T>> validate(T object) {
        return validator.validate(object);
    }

    /**
     * 校验对象并抛出异常
     * @param object 待校验的对象
     * @param <T> 对象类型
     * @throws IllegalArgumentException 如果校验不通过
     */
    public static <T> void validateAndThrow(T object) {
        Set<ConstraintViolation<T>> violations = validate(object);
        if (!violations.isEmpty()) {
            throw new IllegalArgumentException(
                    violations.stream()
                            .map(v -> v.getPropertyPath() + ": " + v.getMessage())
                            .reduce((s1, s2) -> s1 + "; " + s2)
                            .orElse("校验失败"));
        }
    }

    /**
     * 校验对象的指定属性
     * @param object 待校验的对象
     * @param propertyName 属性名
     * @param <T> 对象类型
     * @return 校验结果，如果通过校验则返回空集合
     */
    public static <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName) {
        return validator.validateProperty(object, propertyName);
    }

    /**
     * 校验指定值是否符合指定类的约束
     * @param beanType 包含约束注解的类
     * @param propertyName 属性名
     * @param value 要校验的值
     * @param <T> 对象类型
     * @return 校验结果，如果通过校验则返回空集合
     */
    public static <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value) {
        return validator.validateValue(beanType, propertyName, value);
    }

    /**
     * 快速校验方法，返回是否通过校验
     * @param object 待校验的对象
     * @param <T> 对象类型
     * @return 通过校验返回true，否则返回false
     */
    public static <T> boolean isValid(T object) {
        return validate(object).isEmpty();
    }

    /**
     * 获取校验错误信息
     * @param violations 校验结果集合
     * @param <T> 对象类型
     * @return 拼接后的错误信息
     */
    public static <T> String getErrorMessages(Set<ConstraintViolation<T>> violations) {
        if (violations == null || violations.isEmpty()) {
            return "";
        }
        return violations.stream()
                .map(v -> v.getPropertyPath() + ": " + v.getMessage())
                .reduce((s1, s2) -> s1 + "; " + s2)
                .orElse("");
    }
}